#include "scheduler.h"

Scheduler::Scheduler(Scenario *scenario, int heuristic_id, int error, long double gridUnavailability) {
	/*Scenario*/
	this->scenario = scenario;
	/*Get the Partioner */
	this->adaptivePartioner = scenario->getAdaptivePartioner();
	/*Get the Job to be scheduled*/
	this->job = scenario->getJob();
	/*Get the grid to be used by the job*/
	this->grid = scenario->getGrid();

	/*Instantiate the scheduling heuristic to be used*/
	if (error==WITH_ERROR) {
		this->setHeuristic(heuristic_id, scenario->getErrorRate());
	} else {
		this->setHeuristic(heuristic_id, 0.0);		
	}
	
//	/*Initially, all input data is stored at base site*/
//	for (int t = 0; t< job->getNumberOfTasks(); t++) {
//		DataElement *taskInput = job->getTaskByIndex(t)->getDataInput();
//		Storage *storageBaseSite = grid->getSiteByIndex(0)->getStorage();
//		
//		storageBaseSite->addData(taskInput->getName(), taskInput->getSize(), taskInput->getType());
//	}
}

Scheduler::~Scheduler() {
	if (this->heuristic) delete this->heuristic;
	this->heuristic = NULL;
}

void Scheduler::setHeuristic(int heuristic_id, long double error_rate) {
	switch (heuristic_id) {
		case STOAFF:
			this->heuristic = new StorageAffinity();
			break;
		case XSUFF:
			this->heuristic = new XSufferage(error_rate);			
			break;
		case INFOADAPT:
			this->heuristic = new InformationAdaptability();			
			break;
		case WQR:
			this->heuristic = new Workqueuewr();			
			break;
		case RUMR:
			this->heuristic = new Rumr( scenario->getJobInputSize(), error_rate);
			break;
		default:
			throw std::runtime_error("Invalid Heuristic!");
			break;
	}

	this->heuristic->setAdaptivePartioner(this->adaptivePartioner);

}

SchedulingHeuristic *Scheduler::getHeuristic() {
	return this->heuristic;
}

long double Scheduler::schedule() {
	return heuristic->schedule(this->grid, this->job);
}

void Scheduler::resetJob() {
	this->job->resetTasks();
}

void Scheduler::updateGridResourcesOffset(long double new_offset) {
	this->grid->updateOffsetOfAllResources(new_offset);
}
